*/
static int xhci_queue_req(struct urb *urb)
{
+ unsigned long flags;
usbif_request_t *req;
usbif_front_ring_t *usb_ring = &xhci->usb_ring;
usbif->resp_prod, xhci->usb_resp_cons);
#endif
+ spin_lock_irqsave(&xhci->ring_lock, flags);
if ( RING_FULL(usb_ring) )
{
printk(KERN_WARNING
"xhci_queue_req(): USB ring full, not queuing request\n");
+ spin_unlock_irqrestore(&xhci->ring_lock, flags);
return -ENOBUFS;
}
usb_ring->req_prod_pvt++;
RING_PUSH_REQUESTS(usb_ring);
+ spin_unlock_irqrestore(&xhci->ring_lock, flags);
+
notify_via_evtchn(xhci->evtchn);
DPRINTK("Queued request for an URB.\n");
virt_to_machine(&usbif->req_prod),
usbif->resp_prod, xhci->usb_resp_cons);
#endif
-
+
+ /* This is always called from the timer interrupt. */
+ spin_lock(&xhci->ring_lock);
+
if ( RING_FULL(usb_ring) )
{
printk(KERN_WARNING
"xhci_queue_probe(): ring full, not queuing request\n");
+ spin_unlock(&xhci->ring_lock);
return NULL;
}
usb_ring->req_prod_pvt++;
RING_PUSH_REQUESTS(usb_ring);
+ spin_unlock(&xhci->ring_lock);
+
notify_via_evtchn(xhci->evtchn);
return req;
usbif_request_t *req;
usbif_front_ring_t *usb_ring = &xhci->usb_ring;
+ /* Only ever happens from process context (hub thread). */
+ spin_lock_irq(&xhci->ring_lock);
+
+ if ( RING_FULL(usb_ring) )
+ {
+ printk(KERN_WARNING
+ "xhci_port_reset(): ring full, not queuing request\n");
+ spin_unlock_irq(&xhci->ring_lock);
+ return -ENOBUFS;
+ }
+
/* We only reset one port at a time, so we only need one variable per
* hub. */
xhci->awaiting_reset = 1;
usb_ring->req_prod_pvt++;
RING_PUSH_REQUESTS(usb_ring);
+ spin_unlock_irq(&xhci->ring_lock);
+
notify_via_evtchn(xhci->evtchn);
while ( xhci->awaiting_reset > 0 )
xhci->rh.numports = status->num_ports;
xhci->rh.ports = kmalloc (sizeof(xhci_port_t) * xhci->rh.numports, GFP_KERNEL);
+
+ if ( xhci->rh.ports == NULL )
+ goto alloc_ports_nomem;
+
memset(xhci->rh.ports, 0, sizeof(xhci_port_t) * xhci->rh.numports);
usb_connect(xhci->rh.dev);
xhci->evtchn, xhci->irq);
xhci->state = USBIF_STATE_CONNECTED;
-
+
break;
default:
status->status);
break;
}
+
+ return;
+
+ alloc_ports_nomem:
+ printk(KERN_WARNING "Failed to allocate port memory, XHCI failed to connect.\n");
+ return;
}
/**